﻿/*
 * @Autor: PK
 * @Date: 2021-03-31 13:34:14
 * @Description: 和AgencyChain组合使用，内部服务台请继承这个类而不是Agency
 */

using System;
using O2DESNet;
using ShkSimulation.core.exceptions;
using ShkSimulation.core.template.customer;

namespace ShkSimulation.core.template.agency {
	
    public abstract class InternalAgency: Sandbox {
	    
        /**
         * @description: 当前Agency是否处于某个服务Chain中
         */
        public InternalAgencyChain Chain { get; set; }
        
        public abstract InternalAgencyServeTime ServeTime { get; set; }
        
        public Agency ParentAgency { get; set; }

        public abstract InternalServeResult BeforeParentArrive(Customer customer);

        public abstract InternalServeResult BeforeParentServe(Customer customer);

        public abstract InternalServeResult BeforeParentDepart(Customer customer);

        internal void Arrive(Customer customer) {
	        InternalServeResult result = BeforeParentArrive(customer);
	        if (result.ServeStatus == InternalServeStatusEnum.Scheduled) {
		        // 不马上结束
		        base.Schedule(() => {
			        //TODO
			        result.ScheduleAction?.Invoke();
			        Chain.ChainArrive(customer);
		        }, result.ScheduledTime);
	        }else if (result.ServeStatus == InternalServeStatusEnum.Continue) {
		        Chain.ChainArrive(customer);
	        }
        }

        internal void Serve(Customer customer) {
	        InternalServeResult result = BeforeParentServe(customer);
	        if (result.ServeStatus == InternalServeStatusEnum.Scheduled) {
		        // 不马上结束
		        base.Schedule(() => {
			        result.ScheduleAction?.Invoke();
			        Chain.ChainServe(customer);
		        }, result.ScheduledTime);
	        }else if (result.ServeStatus == InternalServeStatusEnum.Continue) {
		        Chain.ChainServe(customer);
	        }
        }

        internal void Depart(Customer customer) {
	        InternalServeResult result = BeforeParentDepart(customer);
	        if (result.ServeStatus == InternalServeStatusEnum.Scheduled) {
		        // 不马上结束
		        base.Schedule(() => {
				    result.ScheduleAction?.Invoke();
			        Chain.ChainDepart(customer);
		        }, result.ScheduledTime);
	        }else if (result.ServeStatus == InternalServeStatusEnum.Continue) {
		        Chain.ChainDepart(customer);
	        }
        }
        
        protected new void Schedule(Action action, DateTime clockTime, string tag = null) {
	        throw new ErrorParamException("不要用");
        }
        protected new void Schedule(Action action, TimeSpan delay, string tag = null) {
	        throw new ErrorParamException("不要用");
        }
        protected new void Schedule(Action action, string tag = null) {
	        throw new ErrorParamException("不要用");
        }

    }
}
